import java.math.BigDecimal;

/**
 * 
 */

/**
 * @author svenb
 *
 * Abstract class to support CheckingAccount, SavingsAccount and CreditCard
 * 
 *
 */
public class Account {

	protected Customer accountHolder;
	protected BigDecimal balance = new BigDecimal(0);
	protected int accountNumber;
	protected static BigDecimal costs = new BigDecimal(1); 		// per period there is a cost associated with this account
																// that equals 1 pound
	protected static int nextAccountNumber = 0;

	/**
	 *  Set the BigDecimal scale and rounding every time.
	 *  Scale is the number of digits past the decimal to show.
	 *  ROUND_HALF_UP means BigDecimal will always round .5 up to 1.
	 *  
	 *  Customer() populates default values. Mostly to avoid null
	 *  values if it is forgotten.
	 */
	public Account(){
		balance.setScale(2, BigDecimal.ROUND_HALF_UP);
		accountHolder = new Customer();
	}

	/**
	 * nextAccountNumber is static, so it won't
	 * give out the same account number twice to 
	 * different objects that inherit it.
	 * 
	 * @param acctCustomer
	 */
	public Account(Customer acctCustomer)
	{
		balance.setScale(2, BigDecimal.ROUND_HALF_UP);
		accountHolder = acctCustomer;
		accountNumber = nextAccountNumber;
		nextAccountNumber++;
	}
	
	/**
	 * This constructor is only used to find the index
	 * of accounts in the Bank Vectors.
	 * 
	 * @param accountNumber
	 */
	public Account(int accountNumber)
	{
		balance.setScale(2, BigDecimal.ROUND_HALF_UP);
		accountHolder = new Customer();
		this.accountNumber = accountNumber;
	}	
	
	/**
	 * Subtract an amount from balance not greater than balance.
	 * 
	 * BigDecimal.compareTo returns 0 if equal, 1 if first is > -1 if first is <
	 * 
	 * @param amount
	 * @return
	 */
	public boolean withdrawal(BigDecimal amount)
	{
		if(this.balance.subtract(amount).compareTo(new BigDecimal(0)) == -1){
			return false;
		}
		else{
			this.balance = this.balance.subtract(amount);
			return true;
		}
	}	

	/**
	 * Returns true for consistency between methods.
	 * 
	 * @param amount
	 * @return
	 */	
	public boolean deposit(BigDecimal amount)
	{
		this.balance = this.balance.add(amount);
		return true;
	}
	
	public BigDecimal getBalance()
	{
		return balance;
	}
	
	public int getAccountNumber() 
	{
		return accountNumber;
	}
	
	/**
	 * I don't like having output in this class,
	 * but since it is the only output generated
	 * I couldn't rationalize making it separate.
	 * 
	 * Just the same, should probably live in some 
	 * kind of output class.
	 * 
	 * @param type
	 */
	public void print(String type)
	{
		System.out.println("**************************************");
		System.out.println(type+" account:     " + this.accountNumber);
		System.out.println("Account holder name: " + this.accountHolder.getName());
		System.out.println("Address:             " + this.accountHolder.getStreetAddress());
		System.out.print("                     " + this.accountHolder.getZipcode());
		System.out.println(" " + this.accountHolder.getTown());
		System.out.println(this.accountHolder.getCountry().toUpperCase());
		System.out.println("**************************************");
		System.out.println("Balance:  " + balance);
		System.out.println("**************************************");
	}
	
}
